package com.duojuhe.coremodule.help.service.impl;

import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.constant.DataScopeConstants;
import com.duojuhe.common.constant.SystemConstants;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.idgenerator.UUIDUtils;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.common.utils.tree.TreeBaseBean;
import com.duojuhe.common.utils.tree.TreeUtil;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.help.entity.HelpCategory;
import com.duojuhe.coremodule.help.entity.HelpInfo;
import com.duojuhe.coremodule.help.mapper.HelpCategoryMapper;
import com.duojuhe.coremodule.help.mapper.HelpInfoMapper;
import com.duojuhe.coremodule.help.pojo.dto.category.*;
import com.duojuhe.coremodule.help.service.HelpCategoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class HelpCategoryServiceImpl extends BaseService implements HelpCategoryService {
    @Resource
    private HelpCategoryMapper helpCategoryMapper;
    @Resource
    private HelpInfoMapper helpInfoMapper;
    /**
     * 【查询所有信息分类】查询可供前端管理
     * @param req
     * @return
     */
    @DataScopeFilter
    @Override
    public ServiceResult<List<QueryHelpCategoryTreeRes>> queryHelpCategoryTreeResList(QueryHelpCategoryTreeReq req) {
        PageHelperUtil.defaultOrderBy("sort desc,createTime desc,categoryId desc");
        List<QueryHelpCategoryTreeRes> deptList = helpCategoryMapper.queryHelpCategoryTreeResList(req);
        List<TreeBaseBean> tList = TreeUtil.treeList(deptList);
        return ServiceResult.ok(tList);
    }


    /**
     * 【查询所有信息分类】查询可供前端选择使用的信息分类
     * @param req
     * @return
     */
    @DataScopeFilter(dataScope = DataScopeConstants.TENANT_ALL_DATA)
    @Override
    public ServiceResult<List<QueryHelpCategoryTreeRes>> querySelectHelpCategoryTreeResList(QueryHelpCategoryTreeReq req) {
        PageHelperUtil.defaultOrderBy("sort desc,createTime desc,categoryId desc");
        List<QueryHelpCategoryTreeRes> deptList = helpCategoryMapper.queryHelpCategoryTreeResList(req);
        List<TreeBaseBean> tList = TreeUtil.treeList(deptList);
        return ServiceResult.ok(tList);
    }

    /**
     * 【保存】信息分类信息
     * @param req
     * @return
     */
    @Override
    public ServiceResult saveHelpCategory(SaveHelpCategoryReq req) {
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //信息分类ID
        String categoryId = UUIDUtils.getUUID32();
        //获取父级信息分类对象
        BuildParentHelpCategoryReq buildParentInfoCategory = buildParentHelpCategoryReqByParentId(req.getParentId(),categoryId,userTokenInfoVo);
        //租户id
        String tenantId = buildParentInfoCategory.getTenantId();
        //检查分类名称
        checkHelpCategoryName(req.getCategoryName(),tenantId);
        //信息分类层级路径
        String categoryPath = buildParentInfoCategory.getCategoryPath();
        //信息分类父级ID
        String parentId = buildParentInfoCategory.getParentId();
        //创建分类所属部门
        String createDeptId = buildParentInfoCategory.getCreateDeptId();
        //当前时间
        Date date = new Date();
        HelpCategory helpCategory = new HelpCategory();
        helpCategory.setCategoryId(categoryId);
        helpCategory.setParentId(parentId);
        helpCategory.setCategoryName(req.getCategoryName());
        helpCategory.setCategoryPath(categoryPath);
        helpCategory.setCreateTime(date);
        helpCategory.setUpdateTime(date);
        helpCategory.setSort(req.getSort());
        helpCategory.setCreateUserId(userTokenInfoVo.getUserId());
        helpCategory.setUpdateUserId(userTokenInfoVo.getUserId());
        helpCategory.setCreateDeptId(createDeptId);
        helpCategory.setTenantId(tenantId);
        helpCategoryMapper.insertSelective(helpCategory);
        return ServiceResult.ok(categoryId);
    }

    /**
     * 【修改】信息分类信息
     * @param req
     * @return
     */
    @Override
    public ServiceResult updateHelpCategory(UpdateHelpCategoryReq req) {
        //分类id
        String categoryId = req.getCategoryId();
        HelpCategory helpCategoryOld = helpCategoryMapper.selectByPrimaryKey(categoryId);
        if (helpCategoryOld == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //当前登录人
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //获取父级信息分类对象
        BuildParentHelpCategoryReq buildParentInfoCategory = buildParentHelpCategoryReqByParentId(req.getParentId(),categoryId,userTokenInfoVo);
        //信息分类层级路径
        String categoryPath = buildParentInfoCategory.getCategoryPath();
        //信息分类父级ID
        String parentId = buildParentInfoCategory.getParentId();
        //租户id
        String tenantId = buildParentInfoCategory.getTenantId();
        //创建分类所属部门
        String createDeptId = buildParentInfoCategory.getCreateDeptId();
        //检查信息分类名称是不是自己
        if (!helpCategoryOld.getCategoryName().equals(req.getCategoryName())){
            //检查分类名称
            checkHelpCategoryName(req.getCategoryName(),tenantId);
        }
        //检查父级ID是不是自己
        if (helpCategoryOld.getCategoryId().equals(parentId)) {
            return ServiceResult.fail(ErrorCodes.HELP_CATEGORY_PARENT_NOT_SELF);
        }
        //检查父级ID是不是自己的下级
        if (!StringUtils.equals(SystemConstants.UNKNOWN_ID, parentId)) {
            if (checkChildren(parentId, helpCategoryOld.getCategoryId())) {
                return ServiceResult.fail(ErrorCodes.HELP_CATEGORY_PARENT_NOT_SELF_CHILDREN);
            }
        }

        //当前时间
        Date date = new Date();
        HelpCategory helpCategory = new HelpCategory();
        helpCategory.setCategoryId(categoryId);
        helpCategory.setParentId(parentId);
        helpCategory.setCategoryName(req.getCategoryName());
        helpCategory.setCategoryPath(categoryPath);
        helpCategory.setUpdateTime(date);
        helpCategory.setSort(req.getSort());
        helpCategory.setUpdateUserId(userTokenInfoVo.getUserId());
        helpCategory.setCreateDeptId(createDeptId);
        helpCategory.setTenantId(tenantId);
        helpCategoryMapper.updateByPrimaryKeySelective(helpCategory);
        return ServiceResult.ok(categoryId);
    }

    /**
     * 【删除】根据信息分类ID删除信息分类，注意一次仅能删除一个信息分类，存在绑定关系的则不能删除
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResult deleteHelpCategoryByCategoryId(HelpCategoryIdReq req) {
        String categoryId = req.getCategoryId();
        HelpCategory helpCategory = helpCategoryMapper.selectByPrimaryKey(categoryId);
        if (helpCategory == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //检查是否存在子分类信息
        checkHelpCategoryChildren(categoryId);
        //判断分类是否被信息关联使用
        checkRelationHelpInfo(categoryId);
        //分类删除
        helpCategoryMapper.deleteByPrimaryKey(categoryId);
        return ServiceResult.ok(categoryId);
    }


    /**
     * 【私有方法，辅助其他接口方法使用】 根据分类id查询是否存在发布信息关联
     */
    private void checkRelationHelpInfo(String categoryId) {
        if (StringUtils.isBlank(categoryId)){
            throw new DuoJuHeException(ErrorCodes.HELP_CATEGORY_RELATION_NEWS_NOT_DELETE);
        }
        Example example = new Example(HelpInfo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("categoryId", categoryId);
        if(helpInfoMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.HELP_CATEGORY_RELATION_NEWS_NOT_DELETE);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查是否存在子分类信息
     */
    private void checkHelpCategoryChildren(String parentId) {
        if (StringUtils.isBlank(parentId)){
            throw new DuoJuHeException(ErrorCodes.HELP_CATEGORY_EXIST_CHILDREN_NOT_DELETE);
        }
        Example example = new Example(HelpCategory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId", parentId);
        if (helpCategoryMapper.selectByExample(example).size() > 0) {
            throw new DuoJuHeException(ErrorCodes.HELP_CATEGORY_EXIST_CHILDREN_NOT_DELETE);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 查询分类名称是否已经存在
     */
    private void checkHelpCategoryName(String categoryName,String tenantId) {
        if (StringUtils.isBlank(categoryName) || StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.HELP_CATEGORY_NAME_EXIST);
        }
        Example example = new Example(HelpCategory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("categoryName", categoryName);
        criteria.andEqualTo("tenantId", tenantId);
        if(helpCategoryMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.HELP_CATEGORY_NAME_EXIST);
        }
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检测所选项是不是当前id的子项
     */
    private boolean checkChildren(String categoryId, String parentId) {
        if (StringUtils.isBlank(categoryId)){
            return true;
        }
        HelpCategory helpCategory = helpCategoryMapper.selectByPrimaryKey(categoryId);
        if (helpCategory==null){
            return true;
        }
        String newPid = helpCategory.getParentId();
        if (newPid.equals(parentId)) {
            return true;
        } else {
            if (!StringUtils.equals(newPid, SystemConstants.UNKNOWN_ID)
                    && !StringUtils.equals(newPid, parentId)) {
                checkChildren(parentId, newPid);
            }
        }
        return false;
    }


    /**
     * 获取父级
     * @param parentId
     * @return
     */
    private BuildParentHelpCategoryReq buildParentHelpCategoryReqByParentId(String parentId, String categoryId, UserTokenInfoVo userTokenInfoVo){
        BuildParentHelpCategoryReq buildParentHelpCategoryReq = new BuildParentHelpCategoryReq();
        //默认为顶级信息分类，用-1标识
        if (!StringUtils.equals(SystemConstants.UNKNOWN_ID, parentId) && StringUtils.isNotBlank(parentId)) {
            HelpCategory helpCategory = helpCategoryMapper.selectByPrimaryKey(parentId);
            if (helpCategory == null) {
                throw new DuoJuHeException(ErrorCodes.PARENT_PARAM_ERROR);
            }
            if (!StringUtils.equals(SystemConstants.UNKNOWN_ID, helpCategory.getParentId())){
                throw new DuoJuHeException(ErrorCodes.PARENT_PARAM_ERROR);
            }
            buildParentHelpCategoryReq.setCategoryPath(helpCategory.getCategoryPath() + "/" + categoryId);
            buildParentHelpCategoryReq.setParentId(helpCategory.getCategoryId());
            buildParentHelpCategoryReq.setTenantId(helpCategory.getTenantId());
            buildParentHelpCategoryReq.setCreateDeptId(helpCategory.getCreateDeptId());
        }else{
            buildParentHelpCategoryReq.setCategoryPath("/" + categoryId);
            buildParentHelpCategoryReq.setParentId(SystemConstants.UNKNOWN_ID);
            buildParentHelpCategoryReq.setTenantId(userTokenInfoVo.getTenantId());
            buildParentHelpCategoryReq.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        }
        return buildParentHelpCategoryReq;
    }
}
